package com.syh.jn.scm.domain.driver.entity.logistics;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.domain.AbstractSimpleAggregate;
import com.syh.jn.scm.domain.driver.repository.logistics.DriverLogisticsBillReadRepository;
import com.syh.jn.scm.domain.supplier.entity.base.Storehouse;
import com.syh.jn.scm.domain.supplier.entity.purchase.PurchaseOrder;
import com.syh.jn.scm.domain.supplier.entity.purchase.PurchaseReturnOrder;
import com.syh.jn.scm.domain.supplier.entity.sale.SaleOrder;
import com.syh.jn.scm.domain.supplier.entity.sale.SaleReturnOrder;
import com.syh.jn.scm.domain.supplier.repository.base.StorehouseReadRepository;
import com.syh.jn.scm.domain.supplier.repository.purchase.PurchaseOrderReadRepository;
import com.syh.jn.scm.domain.supplier.repository.purchase.PurchaseReturnOrderRepository;
import com.syh.jn.scm.domain.supplier.repository.sale.SaleOrderReadRepository;
import com.syh.jn.scm.domain.supplier.repository.sale.SaleReturnOrderReadRepository;
import com.syh.jn.scm.dto.driver.logistics.DriverLogisticsBillSto;
import com.syh.jn.scm.exception.BusinessException;
import com.syh.jn.scm.service.api.supplier.logistics.enums.LogisticsBillEnums;
import com.syh.jn.scm.service.api.supplier.purchase.enums.PurchaseOrderEnums;
import com.syh.jn.scm.service.api.supplier.purchase.enums.PurchaseReturnOrderEnums;
import com.syh.jn.scm.service.api.supplier.sale.enums.SaleOrderEnums;
import com.syh.jn.scm.service.api.supplier.sale.enums.SaleReturnOrderEnums;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;

/**
 * 采购单聚合
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class DriverLogisticsBill extends AbstractSimpleAggregate<Long> {
  /**
   * 物流单编号
   */
  private String code;
  /**
   * 对应订单id
   */
  private Long orderId;
  /**
   * 订单类型
   */
  private Short orderType;
  /**
   * 客户类型
   */
  private Short customerType;
  /**
   * 客户id
   */
  private Long customerId;
  /**
   * 物流状态(0：未发车 1:已发车 2：已收货)
   */
  private Short logisticsState;
  /**
   * 物流单物流结算状态(0：未生成对账单 1：已生成对账单 -1：已取消)
   */
  private Short statementState;
  /**
   * 发货仓库id
   */
  private Long depotId;
  /**
   * 对应物流对账单id
   */
  private Long statementId;
  /**
   * 物流类型(1:空运 2:陆运 3:海运)
   */
  private Short logisticsType;
  /**
   * 物流公司id
   */
  private Long logisticsCompanyId;
  /**
   * 航班号
   */
  private String flightNumber;
  /**
   * 海航号
   */
  private String shippingNumber;
  /**
   * 货车车牌号
   */
  private String plateNumber;
  /**
   * 预计到达时间(物流)
   */
  private Long etaDateTimestamp;
  /**
   * 司机姓名
   */
  private String driverName;
  /**
   * 司机联系电话
   */
  private String driverContactPhone;
  /**
   * 发货备注(物流)
   */
  private String deliveryNotes;
  /**
   * 发货地区编码
   */
  private String deliveryDeliAreaCode;
  /**
   * 发货地址省 市 区
   */
  private String deliveryDeliArea;
  /**
   * 发货人详细地址
   */
  private String deliveryDeliAddress;
  /**
   * 上传发货图片URL
   */
  private String deliveryCarImgUrl;
  /**
   * 上传发货图片URL
   */
  private String deliveryContractImgUrl;
  /**
   * 发货位置信息
   */
  private String deliveryPosition;
  /**
   * 发货时间
   */
  private Long deliveryTimestamp;
  /**
   * 运费承担方(-1:卖家承担  1:买家承担费用)
   */
  private Short freightTake;
  /**
   * 运费金额
   */
  private BigDecimal totalFreight;
  /**
   * 收货人姓名
   */
  private String deliName;
  /**
   * 收货人联系电话
   */
  private String deliTel;
  /**
   * 要求到货时间
   */
  private Long receiveTimestamp;
  /**
   * 收货地区编码
   */
  private String deliAreaCode;
  /**
   * 收货地址省 市 区
   */
  private String deliArea;
  /**
   * 收货人详细地址
   */
  private String deliAddress;
  /**
   * 上传收货图片URL
   */
  private String collectContractImgUrl;
  /**
   * 收货位置信息
   */
  private String collectPosition;
  /**
   * 入库时间(收货)
   */
  private Long storageTimestamp;
  /**
   * 归属服务商id
   */
  private Long businessEntityId;

  public DriverLogisticsBill(DriverLogisticsBillSto sto) {
    DriverLogisticsBillReadRepository billReadRepository = (DriverLogisticsBillReadRepository) SpringContextUtils.getBean(DriverLogisticsBillReadRepository.class);
    DriverLogisticsBill logisticsBill = billReadRepository.getById(sto.getId());

    ExtBeanUtils.copyProperties(sto, logisticsBill, false);
    ExtBeanUtils.copyProperties(logisticsBill, this, false);
  }

  //发货
  public void delivery() {
    if (this.logisticsState == null || !this.logisticsState.equals(LogisticsBillEnums.State.UNDELIVERY.getStatus()))
      throw new BusinessException("物流单据状态不是待发车，确认发货失败！");
    if (StringUtils.isEmpty(this.deliveryCarImgUrl) || StringUtils.isEmpty(this.deliveryContractImgUrl)
            || StringUtils.isEmpty(this.deliveryPosition))
      throw new BusinessException("发货图片和发货位置信息不能为空");
    this.juStatement(0);
    this.deliveryTimestamp = System.currentTimeMillis();
    this.logisticsState = LogisticsBillEnums.State.DELIVEED.getStatus();
  }

  //收货
  public void collect() {
    //TODO 直采直销单因运费问题 需在服务商手动发货 可能存在采购发货后物流未发货的情况 所有加个判断 提醒司机联系服务商确认销售发货
    if (this.logisticsState == null || !this.logisticsState.equals(LogisticsBillEnums.State.DELIVEED.getStatus())) {
      throw new BusinessException("服务商未确认运费承担方式，确认收货失败！");
    }
    if (this.logisticsState == null || !this.logisticsState.equals(LogisticsBillEnums.State.DELIVEED.getStatus())) {
      throw new BusinessException("物流单据状态不是已发车，确认收货失败！");
    }
    if (StringUtils.isEmpty(this.collectContractImgUrl) || StringUtils.isEmpty(this.collectPosition)) {
      throw new BusinessException("收货图片和收货位置信息不能为空");
    }
    this.juStatement(1);
    if (this.orderType.equals(LogisticsBillEnums.OrderType.PURCHASE.getStatus())) {
      Wrapper we = Wrapper.build();
      we.append(Restrictions.eq("businessEntityId", this.getBusinessEntityId())).append(Restrictions.eq("status", Short.valueOf("1")));
      StorehouseReadRepository storehouseRepository = (StorehouseReadRepository) SpringContextUtils.getBean(StorehouseReadRepository.class);
      Storehouse storehouse = storehouseRepository.getOne(we);
      if (storehouse == null) {
        throw new BusinessException("找不到收货仓库,签收失败,请联系服务商");
      }
      this.depotId = storehouse.getId();
    }
    this.storageTimestamp = System.currentTimeMillis();
    this.logisticsState = LogisticsBillEnums.State.SIGNIN.getStatus();
  }

  /**
   * 判断订单是否已生成对账单
   *
   * @param type
   */
  private void juStatement(int type) {
    //0发货 1收货
    switch (type) {
      case 0:
        if (this.orderType.equals(LogisticsBillEnums.OrderType.SALE.getStatus())) {
          SaleOrderReadRepository saleOrderReadRepository = (SaleOrderReadRepository) SpringContextUtils.getBean("saleOrderRepositoryImpl");
          SaleOrder saleOrder = saleOrderReadRepository.getById(this.orderId);
          if (saleOrder.getOrdState().equals(SaleOrderEnums.State.STATEMENT.getStatus())) {
            throw new BusinessException("销售单" + saleOrder.getCode() + "已生成对账单，无法再修改相关信息！");
          }
        }
        if (this.orderType.equals(LogisticsBillEnums.OrderType.RETURN_PURCHASE.getStatus())) {
          PurchaseReturnOrderRepository purchaseReturnOrderRepository = (PurchaseReturnOrderRepository) SpringContextUtils.getBean(PurchaseReturnOrderRepository.class);
          PurchaseReturnOrder purchaseReturnOrder = purchaseReturnOrderRepository.getById(this.orderId);
          if (purchaseReturnOrder.getReturnOrdState().equals(PurchaseReturnOrderEnums.OrdState.STATEMENT.getStatus())) {
            throw new BusinessException("采购退货单" + purchaseReturnOrder.getReturnCode() + "已生成对账单，无法再修改相关信息！");
          }
        }
        break;
      case 1:
        if (this.orderType.equals(LogisticsBillEnums.OrderType.PURCHASE.getStatus())) {
          PurchaseOrderReadRepository purchaseOrderReadRepository = (PurchaseOrderReadRepository) SpringContextUtils.getBean("purchaseOrderRepositoryImpl");
          PurchaseOrder purchaseOrder = purchaseOrderReadRepository.getById(this.orderId);
          if (purchaseOrder.getOrdState().equals(PurchaseOrderEnums.OrdState.STATEMENT.getStatus())) {
            throw new BusinessException("采购单" + purchaseOrder.getCode() + "已生成对账单，无法再修改相关信息！");
          }
        }
        if (this.orderType.equals(LogisticsBillEnums.OrderType.RETURN_SALE.getStatus())) {
          SaleReturnOrderReadRepository saleReturnOrderReadRepository = (SaleReturnOrderReadRepository) SpringContextUtils.getBean(SaleReturnOrderReadRepository.class);
          SaleReturnOrder saleReturnOrder = saleReturnOrderReadRepository.getById(this.orderId);
          if (saleReturnOrder.getReturnOrdState().equals(SaleReturnOrderEnums.State.STATEMENT.getStatus())) {
            throw new BusinessException("销售退货单" + saleReturnOrder.getCode() + "已生成对账单，无法再修改相关信息！");
          }
        }
        break;
    }
  }

}
